// MyTools.ts
class MyTools {
    /**
     * 唯一的随机字符串，用来区分每条数据
     * @returns {string}
     */
    getUid(): string {
      return Number(Math.random().toString().substr(2, 16) + Date.now()).toString(32);
    }
  
    /**
     * 计算时间差
     * @param beginTime {string} 开始时间，格式为 YYYY-MM-DD
     * @param endTime {string} 结束时间，格式为 YYYY-MM-DD
     * @returns {{hours: number, seconds: number, minutes: number, day: number}}
     */
    dealTime(beginTime: string, endTime: string): { day: number, hours: number, minutes: number, seconds: number } {
      const dateBegin = new Date(beginTime);
      const dateEnd = new Date(endTime);
      const dateDiff = dateEnd.getTime() - dateBegin.getTime(); // 时间差的毫秒数
      const day = Math.floor(dateDiff / (24 * 3600 * 1000)); // 计算出相差天数
      const leave1 = dateDiff % (24 * 3600 * 1000); // 计算天数后剩余的毫秒数
      const hours = Math.floor(leave1 / (3600 * 1000)); // 计算出小时数
      const leave2 = leave1 % (3600 * 1000); // 计算小时数后剩余的毫秒数
      const minutes = Math.floor(leave2 / (60 * 1000)); // 计算相差分钟数
      const leave3 = leave2 % (60 * 1000); // 计算分钟数后剩余的毫秒数
      const seconds = Math.round(leave3 / 1000); // 计算相差秒数
      return { day, hours, minutes, seconds };
    }
  
    /**
     * 获取当天日期
     * @returns {string}
     */
    getCurDay(): string {
      const datetime = new Date();
      const year = datetime.getFullYear();
      const month = (datetime.getMonth() + 1).toString().padStart(2, '0');
      const date = datetime.getDate().toString().padStart(2, '0');
      return `${year}-${month}-${date}`;
    }
  
    /**
     * 数组中，某个属性相同的数据放在一块，如把某个日期相同的相连一起
     * @param list 传入的数组
     * @param prop 那个属性相同的数据
     * @returns {T[]}
     */
    margePropData<T>(list: T[], prop: keyof T): T[] {
      const tempArr: Record<string, T[]> = {};
      list.forEach(item => {
        const key = item[prop] as unknown as string;
        if (!tempArr[key]) {
          tempArr[key] = [item];
        } else {
          tempArr[key].push(item);
        }
      });
      return Object.values(tempArr).flat();
    }
  
    /**
     * 合并行
     * @param list
     * @param prop
     * @returns {T[]}
     */
    mergeRows<T>(list: T[], prop: keyof T): T[] {
      list.forEach(ele => (ele['rowspan'] = 1));
      const len = list.length;
      for (let i = 0; i < len; i++) {
        for (let j = i + 1; j < len; j++) {
          if (list[i][prop] === list[j][prop]) {
            list[i]['rowspan']++;
            list[j]['rowspan']--;
          }
        }
        i = i + list[i]['rowspan'] - 1;
      }
      return list;
    }
  
    /**
     * 根据当前数据的位置，在数组中插入数据
     * @param list 想要插入的数组
     * @param index 插入哪个值的后面的下标
     * @param target 插入的目标
     * @returns {T[]}
     */
    insertArrPositionOfIndex<T>(list: T[], index: number, target: T): T[] {
      const leftList = list.slice(0, index + 1);
      const rightList = list.slice(index + 1);
      return [...leftList, target, ...rightList];
    }
  
    /**
     * 校验规则
     * @param list 要校验的数据列表
     * @param require 必填字段列表
     * @returns {string | null}
     */
    verifyRules<T>(list: T[], require: { prop: keyof T; message: string }[]): string | null {
      for (const key of require) {
        const isEmpty = list.every(it => !it[key.prop]);
        if (isEmpty) {
          return key.message;
        }
      }
      return null;
    }
  
    /**
     * 获取元素下标
     * @param dir 为 1：得到正序遍历方法；为 -1： 得到逆序遍历方法。
     * @returns {(function(*, *, *=): (number|number|number))|*}
     */
    findArrIndex(dir: 1 | -1 = 1) {
      return function <T>(array: T[], cb: (value: T, index: number, array: T[]) => boolean, context?: any): number {
        let length = array.length;
        let index = dir >= 0 ? 0 : length - 1;
  
        for (; index >= 0 && index <= length - 1; index += dir) {
          if (cb.call(context, array[index], index, array)) return index;
        }
        return -1;
      };
    }
  }
  
  // 导出一个实例化对象，以便其他模块可以直接导入使用
  export default new MyTools();